#include "linked_stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * @brief 初始化栈
 * @param st 栈指针的指针
 * @param elem_size 每个元素的大小（字节）
 * @param data_destroy 可选的数据销毁函数，用于复杂数据的清理
 * @return 操作状态码
 */
StackStatus stack_init(Stack **st, size_t elem_size) {
    if (st == NULL || elem_size == 0) {
        return STACK_ERR_NULL_PTR;
    }

    *st = malloc(sizeof(Stack));
    if (*st == NULL) {
        return STACK_ERR_MALLOC_FAIL;
    }

    (*st)->top = NULL;
    (*st)->nmemb = 0;
    (*st)->elem_size = elem_size;
    
    return STACK_SUCCESS;
}

/**
 * @brief 判断栈是否为空
 * @param st 栈指针
 * @return 1-空，0-非空
 */
int stack_empty(const Stack *st) {
    return (st == NULL) || (st->top == NULL);
}

/**
 * @brief 获取栈中元素个数
 * @param st 栈指针
 * @return 元素个数，栈为空时返回0
 */
size_t stack_nmemb(const Stack *st) {
    return (st == NULL) ? 0 : st->nmemb;
}

/**
 * @brief 弹出栈顶元素
 * @param st 栈指针
 * @return 操作状态码
 */
StackStatus stack_pop(Stack *st) {
    if (st == NULL) {
        return STACK_ERR_NULL_PTR;
    }
    
    if (stack_empty(st)) {
        return STACK_ERR_EMPTY;
    }

    Node *del_node = st->top;
    st->top = st->top->next;
    
   

    free(del_node->data);
    
    free(del_node);
    st->nmemb--;
    
    return STACK_SUCCESS;
}

/**
 * @brief 获取栈顶元素（不弹出）
 * @param st 栈指针
 * @param data 用于存储栈顶元素的缓冲区，必须由调用者分配足够内存
 * @return 操作状态码
 */
StackStatus stack_top(const Stack *st, void *data) {
    if (st == NULL || data == NULL) {
        return STACK_ERR_NULL_PTR;
    }
    
    if (stack_empty(st)) {
        return STACK_ERR_EMPTY;
    }
    
    // 将数据拷贝到用户提供的缓冲区，避免返回内部指针
    memcpy(data, st->top->data, st->elem_size);
    return STACK_SUCCESS;
}

/**
 * @brief 元素入栈
 * @param st 栈指针
 * @param data 要入栈的数据指针
 * @return 操作状态码
 */
StackStatus stack_push(Stack *st, const void *data) {
    if (st == NULL || data == NULL) {
        return STACK_ERR_NULL_PTR;
    }

    Node *new_node = malloc(sizeof(Node));
    if (new_node == NULL) {
        return STACK_ERR_MALLOC_FAIL;
    }

    new_node->data = malloc(st->elem_size);
    if (new_node->data == NULL) {
        free(new_node);
        return STACK_ERR_MALLOC_FAIL;
    }

    // 拷贝数据到新节点
    memcpy(new_node->data, data, st->elem_size);
    new_node->next = st->top;
    st->top = new_node;
    st->nmemb++;
    
    return STACK_SUCCESS;
}





